package com.t17;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

/**
 * Created by xuyiwei on 2018/8/14.
 */
class SetType{
    int i;
    public SetType(int i) {
        this.i = i;
    }
    public boolean equals(Object o){
        return o instanceof SetType && ( i == ((SetType) o).i);
    }
    public String toString(){
        return Integer.toString(i);
    }
}
class HashType extends SetType {
    public HashType(int i) {
        super(i);
    }
    @Override
    public int hashCode() {
        return i;
    }
}
class TreeType extends SetType  implements Comparable<TreeType> {
    public TreeType(int i) {
        super(i);
    }
    @Override
    public int compareTo(TreeType c) {
        return (c.i<i?-1:(c.i==i?0:1));
    }
}
public class TypesForSets{
    static <T> Set<T> fill(Set<T> set, Class<T> type){
        try{
            for(int i=0;i<10;i++){
                set.add(type.getConstructor(int.class).newInstance(i));
            }
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        return set;
    }
    static <T> void test(Set<T> set, Class<T> type) {
        fill(set, type);
        fill(set, type); // Try to add duplicates
        fill(set, type);
        System.out.println(set);
    }
    public static void main(String[] args) {
        //对于放置到Set的散列实现中的对象 重写hashCode是必须的  因为他是先比较hashCode 在比较equals的
        test(new HashSet<HashType>(), HashType.class);
        test(new LinkedHashSet<HashType>(), HashType.class);
        //对于放置进treeSet中的对象  实现Comparable是必须的 因为他是先比较compareTo  再去比较equals的
        test(new TreeSet<TreeType>(), TreeType.class);
        //如果散列没实现hashCode方法 即使equals想法 hashCode不相等   散列Set也会认为不相等
        test(new HashSet<SetType>(), SetType.class);
        test(new HashSet<TreeType>(), TreeType.class);
        test(new LinkedHashSet<SetType>(), SetType.class);
        test(new LinkedHashSet<TreeType>(), TreeType.class);
        //Treeset没实现Comparable则会报错
        try {  test(new TreeSet<SetType>(), SetType.class);  } catch(Exception e) {  System.out.println(e.getMessage());    }
        try {  test(new TreeSet<HashType>(), HashType.class); } catch(Exception e) { System.out.println(e.getMessage());  }
        /**
         * output[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
         [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
         [7, 1, 3, 6, 9, 6, 5, 5, 4, 8, 0, 3, 5, 9, 3, 8, 4, 4, 2, 6, 2, 1, 0, 7, 2, 8, 7, 0, 9, 1]
         [3, 4, 0, 0, 5, 2, 9, 8, 6, 2, 1, 3, 3, 6, 9, 0, 7, 1, 4, 8, 6, 5, 2, 1, 7, 9, 8, 5, 7, 4]
         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
         java.lang.ClassCastException: com.t17.SetType cannot be cast to java.lang.Comparable
         java.lang.ClassCastException: com.t17.HashType cannot be cast to java.lang.Comparable
         */
    }
}
